package com.jlcloud.core.context.listener;

import com.jlcloud.core.context.JlCloudHttpHeadersGetter;
import com.jlcloud.core.context.props.JlCloudContextProperties;
import lombok.RequiredArgsConstructor;
import org.slf4j.MDC;
import com.jlcloud.core.tool.constant.JlCloudConstant;
import com.jlcloud.core.tool.utils.StringUtil;
import com.jlcloud.core.tool.utils.ThreadLocalUtil;
import org.springframework.http.HttpHeaders;

import jakarta.servlet.ServletRequestEvent;
import jakarta.servlet.ServletRequestListener;
import jakarta.servlet.http.HttpServletRequest;

/**
 * Servlet 请求监听器
 *
 * @author By: JlCloud <br>
 * @Package: com.jlcloud <br>
 * @CreateTime: 2024-12-03 21:45 <br>
 * @Copyright: 2021 www.jilianjituan.com Inc. All rights reserved. <br>
 * @Caution 注意：本内容仅限于冀联人力集团内部传阅，禁止外泄以及用于其他的商业目的 <br>
 */
@RequiredArgsConstructor
public class JlCloudServletRequestListener implements ServletRequestListener {
	private final JlCloudContextProperties contextProperties;
	private final JlCloudHttpHeadersGetter httpHeadersGetter;

	@Override
	public void requestInitialized(ServletRequestEvent event) {
		HttpServletRequest request = (HttpServletRequest) event.getServletRequest();
		// MDC 获取透传的 变量
		JlCloudContextProperties.Headers headers = contextProperties.getHeaders();
		String requestId = request.getHeader(headers.getRequestId());
		if (StringUtil.isNotBlank(requestId)) {
			MDC.put(JlCloudConstant.MDC_REQUEST_ID_KEY, requestId);
		}
		String accountId = request.getHeader(headers.getAccountId());
		if (StringUtil.isNotBlank(accountId)) {
			MDC.put(JlCloudConstant.MDC_ACCOUNT_ID_KEY, accountId);
		}
		String tenantId = request.getHeader(headers.getTenantId());
		if (StringUtil.isNotBlank(tenantId)) {
			MDC.put(JlCloudConstant.MDC_TENANT_ID_KEY, tenantId);
		}
		// 处理 context，直接传递 request，因为 spring 中的尚未初始化完成
		HttpHeaders httpHeaders = httpHeadersGetter.get(request);
		ThreadLocalUtil.put(JlCloudConstant.CONTEXT_KEY, httpHeaders);
	}

	@Override
	public void requestDestroyed(ServletRequestEvent event) {
		// 会话销毁时，清除上下文
		ThreadLocalUtil.clear();
		// 会话销毁时，清除 mdc
		MDC.remove(JlCloudConstant.MDC_REQUEST_ID_KEY);
		MDC.remove(JlCloudConstant.MDC_ACCOUNT_ID_KEY);
		MDC.remove(JlCloudConstant.MDC_TENANT_ID_KEY);
	}

}
